#include "app_mqtt.h"
#include "../thirdparty/log.h"
#include <MQTTClient.h>

static MQTTClient client;
// 初始化一个连接参数的模板
static MQTTClient_connectOptions conn_opts = MQTTClient_connectOptions_initializer;
// 初始化一个消息的模板
static MQTTClient_message pubmsg = MQTTClient_message_initializer;
// 外部程序注册在消息队列模块的回调 ，该回调负责数据接收后的实际处理
static int (*callback_func)(char *data, int len);
// 失联回调
static void app_mqtt_connectionLost(void *context, char *cause)
{
    log_error("connection lost: %s", cause);
    MQTTClient_disconnect(client, 1000);
    MQTTClient_destroy(&client);
}
// 消息到达回调
static int app_mqtt_messageArrived(void *context, char *topicName, int topicLen, MQTTClient_message *message)
{
    // 1 要message的数据内容提取出来
    char *data = message->payload;
    int data_len = message->payloadlen;
    // 2 用外部注册的回调对接收的数据进行后续处理
    int ret = callback_func(data, data_len);
    if (ret < 0)
    {             // 后续处理失败
        return 0; // 失败返回0
    }
    return 1; // 处理成功返回1
}

// 发送成功回调
static void app_mqtt_delivered(void *context, MQTTClient_deliveryToken dt)
{
    log_info("message delivered");
}

/**
 * @brief mqtt初始化
 *
 *
 *  1  mqtt客户端创建   全局一个 （init方法）
    2  客户端回调方法的注册    回调方法，当某种事件触发，由外部自动调用的本地方法。
     三种事件：失联事件、发送成功事件、有消息到达的事件  （init方法）
    3  mqtt客户端要连接服务端 （init方法）
    4  mqtt 要主动订阅服务的某个主题 subscribe
 */
int app_mqtt_init(void)
{
    // 1  mqtt客户端创建   全局一个
    int ret = MQTTClient_create(&client, MQTT_URL, MQTT_CLIENT_ID, MQTTCLIENT_PERSISTENCE_NONE, NULL);
    if (ret != MQTTCLIENT_SUCCESS)
    {
        log_error("MQTTClient_create error\r\n");
        return -1;
    }
    // 2  注册客户端回调函数
    MQTTClient_setCallbacks(client, NULL, app_mqtt_connectionLost, app_mqtt_messageArrived, app_mqtt_delivered);
    // 3  mqtt客户端要连接服务端 （init方法）
    ret = MQTTClient_connect(client, &conn_opts);
    if (ret != MQTTCLIENT_SUCCESS)
    {
        MQTTClient_destroy(&client); // 连接失败就销毁
        log_error("MQTTClient_connect error\r\n");
        return -1;
    }
    // 4  mqtt 要主动订阅服务的某个主题 subscribe
    ret = MQTTClient_subscribe(client, MQTT_SUBSCRIBE_TOPIC, MQTT_QOS);
    if (ret != MQTTCLIENT_SUCCESS)
    {
        MQTTClient_destroy(&client);
        log_error("MQTTClient_subscribe error\r\n");
        return -1;
    }

    return 0;
}

/**
 * @brief 发送数据到服务端
 * @param data 发送的数据
 * @param len 发送数据的长度
 */
int app_mqtt_send(char *data, int len)
{
    // 设置发送消息的参数
    pubmsg.payload = data;
    pubmsg.payloadlen = len;
    pubmsg.qos = MQTT_QOS;
    int ret = MQTTClient_publishMessage(client, MQTT_PUBLISH_TOPIC, &pubmsg, NULL);
    if (ret != MQTTCLIENT_SUCCESS)
    {
        log_error("MQTTClient_publishMessage error\r\n");
        return -1;
    }
    return 0;
}

/**
 *  @brief 注册接受数据后的处理
 *  @param callback 回调函数
 */
int app_mqtt_register_recv(int (*callback)(char *data, int len))
{
    callback_func = callback; // 将外部回调函数赋值给本地回调函数
    return 0;
}

/**
 * @brief 销毁客户端
 */
void app_mqtt_destroy(void)
{
    MQTTClient_disconnect(client, 1000);
    MQTTClient_destroy(&client);
}